package edu.szcu.vitaguard.dao;

import edu.szcu.vitaguard.entity.Registration;
import org.apache.ibatis.annotations.*;

import java.time.LocalDate;
import java.util.List;

/**
 * 预约挂号DAO接口
 */
@Mapper
public interface RegistrationDao {
    
    /**
     * 插入预约挂号
     * @param registration 预约挂号对象
     * @return 影响的行数
     */
    @Insert("INSERT INTO registration(patient_id, doctor_id, schedule_id, reg_date, start_time, end_time, " +
            "reg_type, status, create_time, update_time) " +
            "VALUES(#{patientId}, #{doctorId}, #{scheduleId}, #{regDate}, #{startTime}, #{endTime}, " +
            "#{regType}, #{status}, #{createTime}, #{updateTime})")
    @Options(useGeneratedKeys = true, keyProperty = "regId")
    int insert(Registration registration);
    
    /**
     * 根据ID查询预约挂号
     * @param regId 预约挂号ID
     * @return 预约挂号对象
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id " +
            "WHERE r.reg_id = #{regId}")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    Registration selectById(Integer regId);
    
    /**
     * 查询所有预约挂号
     * @return 预约挂号列表
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    List<Registration> selectAll();
    
    /**
     * 根据患者ID查询预约挂号
     * @param patientId 患者ID
     * @return 预约挂号列表
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id " +
            "WHERE r.patient_id = #{patientId}")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    List<Registration> selectByPatientId(Integer patientId);
    
    /**
     * 根据医生ID查询预约挂号
     * @param doctorId 医生ID
     * @return 预约挂号列表
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id " +
            "WHERE r.doctor_id = #{doctorId}")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    List<Registration> selectByDoctorId(Integer doctorId);
    
    /**
     * 根据排班ID查询预约挂号
     * @param scheduleId 排班ID
     * @return 预约挂号列表
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id " +
            "WHERE r.schedule_id = #{scheduleId}")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    List<Registration> selectByScheduleId(Integer scheduleId);
    
    /**
     * 根据日期查询预约挂号
     * @param regDate 预约日期
     * @return 预约挂号列表
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id " +
            "WHERE r.reg_date = #{regDate}")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    List<Registration> selectByRegDate(LocalDate regDate);
    
    /**
     * 根据状态查询预约挂号
     * @param status 状态
     * @return 预约挂号列表
     */
    @Select("SELECT r.*, p.patient_name, p.gender, p.birth, p.phone, p.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "s.schedule_date, s.start_time as schedule_start_time, s.end_time as schedule_end_time, " +
            "s.max_appointments, s.status as schedule_status " +
            "FROM registration r " +
            "LEFT JOIN patient p ON r.patient_id = p.patient_id " +
            "LEFT JOIN doctor d ON r.doctor_id = d.doctor_id " +
            "LEFT JOIN schedule s ON r.schedule_id = s.schedule_id " +
            "WHERE r.status = #{status}")
    @Results({
        @Result(property = "regId", column = "reg_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "scheduleId", column = "schedule_id"),
        @Result(property = "regDate", column = "reg_date"),
        @Result(property = "startTime", column = "start_time"),
        @Result(property = "endTime", column = "end_time"),
        @Result(property = "regType", column = "reg_type"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "schedule", column = "schedule_id", javaType = edu.szcu.vitaguard.entity.Schedule.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.ScheduleDao.selectById"))
    })
    List<Registration> selectByStatus(String status);
    
    /**
     * 更新预约挂号
     * @param registration 预约挂号对象
     * @return 影响的行数
     */
    @Update("UPDATE registration SET patient_id = #{patientId}, doctor_id = #{doctorId}, " +
            "schedule_id = #{scheduleId}, reg_date = #{regDate}, start_time = #{startTime}, " +
            "end_time = #{endTime}, reg_type = #{regType}, status = #{status}, " +
            "update_time = #{updateTime} " +
            "WHERE reg_id = #{regId}")
    int update(Registration registration);
    
    /**
     * 删除预约挂号
     * @param regId 预约挂号ID
     * @return 影响的行数
     */
    @Delete("DELETE FROM registration WHERE reg_id = #{regId}")
    int deleteById(Integer regId);
}